package com.sky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.sky.annotation.AutoFill;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Category;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.SetmealDish;
import com.sky.enumeration.OperationType;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private SetmealDishMapper setmealDishMapper;


    @AutoFill(OperationType.INSERT)
    //同时操作两个数据库，使用事务
    @Transactional
    @Override
    public Result<String> addDish(DishDTO dishDTO) {

        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        //向菜品表插入数据
        if (!save(dish)) {
            throw new RuntimeException("菜品插入失败！！");
        }
        //插入成功后回显id并将其赋值到flavor中
        //判断flavors是否为null
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (flavors.isEmpty()) {
            //如为空 则不插入flavor
            return Result.success();
        }
        //不为空 -》获取回显的主键并赋值
        flavors.forEach(flavor -> {flavor.setDishId(dish.getId());});
        //插入口味
        Db.saveBatch(dishDTO.getFlavors());

        return Result.success();
    }

    @Override
    public PageResult<DishVO> selectPage(DishPageQueryDTO dishPageQueryDTO) {

        Page<Dish> page = Page.of(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize());
        page.addOrder(OrderItem.desc("update_time"));

        //查询菜品
        Page<Dish> dishPage = lambdaQuery().like(dishPageQueryDTO.getName() != null, Dish::getName, dishPageQueryDTO.getName())
                .eq(dishPageQueryDTO.getStatus() != null, Dish::getStatus, dishPageQueryDTO.getStatus())
                .eq(dishPageQueryDTO.getCategoryId() != null, Dish::getCategoryId, dishPageQueryDTO.getCategoryId())
                .orderByAsc(Dish::getUpdateTime)
                .page(page);

        //再查询category表并做完类型转换
        List<DishVO> collect = dishPage.getRecords().stream().map(item -> {
            DishVO dishVO = new DishVO();
            BeanUtils.copyProperties(item, dishVO);
            dishVO.setCategoryName(Db.lambdaQuery(Category.class).eq(Category::getId, item.getCategoryId()).one().getName());
            return dishVO;

        }).collect(Collectors.toList());

        return new PageResult<>(page.getTotal(), collect);
    }

    //同时操作两个数据库，使用事务
    @Transactional
    @Override
    public void delete(Long[] ids) {

        //判断当前菜品是否能删除--起售（不能）
        List<Long> dishIds = this.lambdaQuery()
                .in(ids != null, Dish::getId, ids)
                .list().stream()
                .filter(dish -> {
                    if (dish.getStatus() == StatusConstant.ENABLE) {
                        throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
                    }
                    return true;
                })
                .map(Dish::getId)
                .collect(Collectors.toList());

        List<SetmealDish> setmealDishes = setmealDishMapper.selectList(new QueryWrapper<SetmealDish>().in("dish_id", dishIds));
        if (setmealDishes.isEmpty()) {
            //判断是否被套餐关联--关联（不能）
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
        }

        //删除菜品
        this.removeBatchByIds(dishIds);
        //删除相关的口味数据
        Db.remove(new QueryWrapper<>().in("dish_id", dishIds));



    }
}
